
package br.com.crednove.controle;

import br.com.crednove.dao.DAOCliente;
import br.com.crednove.modelo.ClienteRefin;
import br.com.crednove.modelo.Excel;
import br.com.crednove.modelo.Parcela;
import br.com.crednove.paineis.PainelFiltroRefin;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;

public class ControleFiltrarRefin {

    private PainelFiltroRefin painel;
    private Excel excel;
    private DAOCliente daoCliente;
    private boolean novo;
    private final String EXTENSAO_IMPORTACAO = ".xls";
    private final String JFILECHOOSER_FILTRO_DESCRICAO = "Arquivos do Excel 97-2003 (.xls)";
    private final String JFILECHOOSER_TITULO = "Abrir";
    private final String EXTENSAO_EXPORTACAO = ".csv";
    private final String JFILECHOOSER_DIRETORIO_FILTRO_DESCRICAO = "Arquivos do Excel 97-2003 (.csv)";
    private final String JFILECHOOSER_DIRETORIO_TITULO = "Salvar";
    private final String tituloErroArquivo = "Erro com extensão do arquivo.";
    private final String msgErroArquivo = " Verifique se o arquivo selecionado é do pacote Office 2003 "
            + "ou anteriores";

    public ControleFiltrarRefin(PainelFiltroRefin painel) {
        this.painel = painel;
        this.daoCliente = new DAOCliente();
        this.novo = false;
    }

    public void btnSelecionarArquivoEvento() {
        File arquivo;
        arquivo = this.selecionarArquivo();
        if (arquivo != null) {
            this.excel = new Excel();
            if (this.excel.abrirArquivo(arquivo)) {
                this.painel.getTxtArquivo().setText(arquivo.getPath());
                if (!"".equals(this.painel.getTxtDiretorio().getText())) {
                    this.painel.getBtnConfirmar().setEnabled(true);
                }
            } else {
                JOptionPane.showMessageDialog(null, this.msgErroArquivo, this.tituloErroArquivo,
                        JOptionPane.ERROR_MESSAGE, null);
            }
        }
    }

    public void btnSelecionarDiretorioEvento() {
        String caminho = this.selecionarDiretorio();
        if (caminho != null) {
            this.painel.getTxtDiretorio().setText(caminho + EXTENSAO_EXPORTACAO);
            if (!"".equals(this.painel.getTxtArquivo().getText())) {
                this.painel.getBtnConfirmar().setEnabled(true);
            }
        }
    }

    public void btnConfirmarEvento() {
        if (this.novo) {
            this.resetar();
            this.novo = false;
        } else {
            this.filtrar();
            this.abilitaInterface(false);
            this.novo = true;
        }
    }

    public void fecharEvento(ControleInicio giControle) {
        this.resetar();
        giControle.mostraPainel(ControleInicio.painelHome);
    }

    private void filtrar() {
        new Thread() {
            @Override
            public void run() {
                try {
                    //Parametros recebidos pelo usuario
                    float minVlParcela = Float.parseFloat(painel.getTxtMinVlParcela().getText().replace(',', '.'));
                    float maxVlParcela = Float.parseFloat(painel.getTxtMaxVlParcela().getText().replace(',', '.'));
                    float minLiquido = Float.parseFloat(painel.getTxtMinVlLiquido().getText().replace(',', '.'));
                    float maxLiquido = Float.parseFloat(painel.getTxtMaxVlLiquido().getText().replace(',', '.'));
                    int minParcelasContrato = (int) painel.getJspMinParcelasCont().getValue();
                    int maxParcelasContrato = (int) painel.getJspMaxParcelasCont().getValue();
                    int minParcelasAberto = (int) painel.getJspMinParcelasAberto().getValue();
                    int maxParcelasAberto = (int) painel.getJspMaxParcelasAberto().getValue();
                    int minParcelasPagas = (int) painel.getJspMinParcelasPagas().getValue();
                    float coeficienteRed = Float.parseFloat(painel.getTxtVlCoeficienteRed().getText().replace(',', '.'));
                    float coeficienteLuc = Float.parseFloat(painel.getTxtVlCoeficienteLuc().getText().replace(',', '.'));
                    //variaveis de auxilio em lógica
                    boolean ok = false, parcelasPagas = false;// variável que indica se cliente passou no filtro ou não
                    int numFiltrados = 0;
                    float margem = 0, novoValorParcela, parcelaSomada, novoLiquido = 0, novoBruto, novoSaldo = 0;

                    FileWriter arquivo = new FileWriter(painel.getTxtDiretorio().getText());
                    FileWriter teste = new FileWriter("C:\\Users\\Suporte\\Desktop\\Planilhas para teste\\teste7.csv");

                    BufferedWriter bfwEscritor = new BufferedWriter(arquivo);
                    BufferedWriter bfwEscritorTeste = new BufferedWriter(teste);
                    daoCliente.conectar();
                    painel.getJpbProgresso().setMinimum(0);
                    painel.getJpbProgresso().setMaximum(excel.getNumLinhasTotal() - 1);

                    escreverCSV("NB;CPF;NOME;DATA_NASCIMENTO;UF;CIDADE;BAIRRO;CEP;ENDERECO;DDD;TELEFONE;ID_BANCO;INICIO_PAGAMENTO;", bfwEscritor);
                    escreverCSV("NB;CPF;NOME;DATA_NASCIMENTO;UF;CIDADE;BAIRRO;CEP;ENDERECO;DDD;TELEFONE;ID_BANCO;INICIO_PAGAMENTO;", bfwEscritorTeste);

                    for (int i = 1; i <= 10; i++) {
                        escreverCSV("Parcelas_Contrato_" + i + ";", bfwEscritor);
                        escreverCSV("Parcelas_Aberto_" + i + ";", bfwEscritor);
                        escreverCSV("Valor_Parcela_" + i + ";", bfwEscritor);
                        escreverCSV("Bruto_" + i + ";", bfwEscritor);
                        escreverCSV("Saldo_Refin_" + i + ";", bfwEscritor);
                        escreverCSV("Liquido_" + i + ";", bfwEscritor);

                        escreverCSV("Parcelas_Contrato_" + i + ";", bfwEscritorTeste);
                        escreverCSV("Parcelas_Aberto_" + i + ";", bfwEscritorTeste);
                        escreverCSV("Valor_Parcela_" + i + ";", bfwEscritorTeste);
                        escreverCSV("Bruto_" + i + ";", bfwEscritorTeste);
                        escreverCSV("Saldo_Refin_" + i + ";", bfwEscritorTeste);
                        escreverCSV("Liquido_" + i + ";", bfwEscritorTeste);
                    }

                    for (int i = 1; i < excel.getNumLinhasTotal(); i++) {
                        ClienteRefin refin = excel.importaClienteRefin(i, coeficienteLuc);
                        painel.getJpbProgresso().setValue(i);
                        ok = false;

                        //Filtro mais importante funcionando
                        for (int j = 0; j < refin.getParcelas().size(); j++) {
                            novoBruto = 0;
                            novoLiquido = 0;
                            novoValorParcela = 0;
                            novoSaldo = 0;

                            Parcela p = refin.getParcelas().get(j);

                            if (p.getLiquido() >= minLiquido && p.getLiquido() <= maxLiquido
                                    && p.getValorParcela() >= minVlParcela && p.getValorParcela() <= maxVlParcela
                                    && p.getParcelasPagas() >= minParcelasPagas) {

                                numFiltrados++;
                                painel.getLblStatus().setText(numFiltrados + " filtrados");
                                refin.setCliente(daoCliente.select(refin.getCliente().getCpf()));
                                escreverCSV("\n" + refin.toString(), bfwEscritor);
                                daoCliente.atualizaTrabalhado(refin.getCliente().getCpf(), true);
                                ok = true;
                                j = refin.getParcelas().size();
                            } else {
                                for (int k = j + 1; k < refin.getParcelas().size(); k++) {
                                    Parcela p1 = refin.getParcelas().get(k);

                                    novoValorParcela = p.getValorParcela() + p1.getValorParcela();
                                    novoSaldo = p.getSaldoRefin() + p1.getSaldoRefin();
                                    novoBruto = p1.calcularBruto(novoValorParcela, coeficienteLuc);
                                    novoLiquido = p1.calcularLiquido(novoBruto, novoSaldo);

                                    if (novoLiquido >= (2 * minLiquido) && novoLiquido <= maxLiquido
                                            && novoValorParcela >= minVlParcela && novoValorParcela <= maxVlParcela
                                            && (p.getParcelasPagas() >= minParcelasPagas || p1.getParcelasPagas() >= minParcelasPagas)) {

                                        numFiltrados++;
                                        painel.getLblStatus().setText(numFiltrados + " filtrados");
                                        refin.setCliente(daoCliente.select(refin.getCliente().getCpf()));
                                        escreverCSV("\n" + refin.toString(), bfwEscritor);
                                        daoCliente.atualizaTrabalhado(refin.getCliente().getCpf(), true);
                                        ok = true;
                                        j = refin.getParcelas().size();
                                        k = refin.getParcelas().size();
                                    } else {

                                        parcelasPagas = false;
                                        for (int l = k - 1; l > j; l--) {
                                            Parcela p2 = refin.getParcelas().get(l);
                                            novoValorParcela = novoValorParcela + p2.getValorParcela();
                                            novoSaldo = novoSaldo + p2.getSaldoRefin();
                                            novoBruto = p2.calcularBruto(novoValorParcela, coeficienteLuc);
                                            novoLiquido = p2.calcularLiquido(novoBruto, novoSaldo);
                                            if (p.getParcelasPagas() >= minParcelasPagas || p1.getParcelasPagas() >= minParcelasPagas
                                                    || p2.getParcelasPagas() >= minParcelasPagas) {
                                                parcelasPagas = true;
                                            }
                                        }

                                        if (novoLiquido >= ((k + 1) * minLiquido) && novoLiquido <= maxLiquido
                                                && novoValorParcela >= minVlParcela && novoValorParcela <= maxVlParcela
                                                && parcelasPagas) {
                                            
                                            
                                            numFiltrados++;
                                            painel.getLblStatus().setText(numFiltrados + " filtrados");
                                            refin.setCliente(daoCliente.select(refin.getCliente().getCpf()));
                                            escreverCSV("\n" + refin.toString(), bfwEscritor);
                                            daoCliente.atualizaTrabalhado(refin.getCliente().getCpf(), true);
                                            ok = true;
                                            j = refin.getParcelas().size();
                                            k = refin.getParcelas().size();
                                        }
                                    }
                                }
                            }
                        }

                        //2ª opção de filtro - Queimando parcelas
                        if (!ok && refin.getParcelas().size() > 1) {
                            refin.ordenarParcelas();

                            for (int j = 0; j < refin.getParcelas().size()-1; j++) {

                                Parcela p = refin.getParcelas().get(j);
                                margem = 0;
                                novoBruto = 0;
                                novoLiquido = 0;
                                novoValorParcela = 0;

                                for (int k = j + 1; k < refin.getParcelas().size(); k++) {
                                    Parcela p1 = refin.getParcelas().get(k);

                                    novoValorParcela = p.calcularParcela(coeficienteRed, minLiquido);
                                    margem = margem + novoValorParcela - p.getValorParcela();
                                    parcelaSomada = p1.getValorParcela() + margem;
                                    novoBruto = p1.calcularBruto(parcelaSomada, coeficienteLuc);
                                    novoLiquido = p1.calcularLiquido(novoBruto, p1.getSaldoRefin());

                                    if (novoLiquido >= (2 * minLiquido) && novoLiquido <= maxLiquido
                                            && parcelaSomada >= minVlParcela && parcelaSomada <= maxVlParcela
                                            && (p.getParcelasPagas() >= minParcelasPagas || p1.getParcelasPagas() >= minParcelasPagas)) {

                                        numFiltrados++;
                                        painel.getLblStatus().setText(numFiltrados + " filtrados");
                                        refin.setCliente(daoCliente.select(refin.getCliente().getCpf()));
                                        escreverCSV("\n" + refin.toString(), bfwEscritor);
                                        daoCliente.atualizaTrabalhado(refin.getCliente().getCpf(), true);
                                        ok = true;
                                        j = refin.getParcelas().size();
                                        k = refin.getParcelas().size();
                                    } else {
                                        parcelasPagas = false;
                                        for (int l = k - 1; l > j; l--) {
                                            Parcela p2 = refin.getParcelas().get(l);
                                            
                                            novoValorParcela = p2.calcularParcela(coeficienteRed, minLiquido);
                                            margem = margem + novoValorParcela - p2.getValorParcela();
                                            parcelaSomada = p1.getValorParcela() + margem;
                                            novoBruto = p1.calcularBruto(parcelaSomada, coeficienteLuc);
                                            novoLiquido = p1.calcularLiquido(novoBruto, p1.getSaldoRefin());
                                            
                                            if (p.getParcelasPagas() >= minParcelasPagas || p1.getParcelasPagas() >= minParcelasPagas
                                                    || p2.getParcelasPagas() >= minParcelasPagas) {
                                                parcelasPagas = true;
                                            }
                                        }

                                        if (novoLiquido >= ((k + 1) * minLiquido) && novoLiquido <= maxLiquido
                                                && parcelaSomada >= minVlParcela && parcelaSomada <= maxVlParcela
                                                && parcelasPagas) {
                                            
                                            numFiltrados++;
                                            painel.getLblStatus().setText(numFiltrados + " filtrados");
                                            refin.setCliente(daoCliente.select(refin.getCliente().getCpf()));
                                            escreverCSV("\n" + refin.toString(), bfwEscritor);
                                            daoCliente.atualizaTrabalhado(refin.getCliente().getCpf(), true);
                                            ok = true;
                                            j = refin.getParcelas().size();
                                            k = refin.getParcelas().size();
                                        }
                                    }
                                }
                            }
                        }  

                        if (!ok) {
                            refin.setCliente(daoCliente.select(refin.getCliente().getCpf()));
                            escreverCSV("\n" + refin.toString(), bfwEscritorTeste);
                        }
                    }

                    daoCliente.desconectar();
                    bfwEscritor.close();
                    bfwEscritorTeste.close();
                    JOptionPane.showMessageDialog(null, "Filtro realizado com sucesso");
                    painel.getBtnConfirmar().setEnabled(true);
                    painel.getBtnConfirmar().setText("Novo");
                } catch (IOException ex) {
                    System.out.println(ex);
                } catch (NumberFormatException ex) {
                    System.out.println(ex);
                    JOptionPane.showMessageDialog(null, "Informe os valores corretamente");
                }
            }
        }.start();
    }

    private void escreverCSV(String conteudo, BufferedWriter writer) {
        try {
            writer.write(conteudo);
            writer.flush();
        } catch (IOException ex) {
            System.out.println(ex + "erro ao escrever cpf na planilha");
        }
    }

    private File selecionarArquivo() {
        JFileChooser seletorArquivo = new JFileChooser();
        seletorArquivo.setFileSelectionMode(JFileChooser.FILES_ONLY);
        seletorArquivo.setDialogTitle(JFILECHOOSER_TITULO);
        seletorArquivo.setFileFilter(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.getName().toLowerCase().endsWith(EXTENSAO_IMPORTACAO) || file.isDirectory();
            }

            @Override
            public String getDescription() {
                return JFILECHOOSER_FILTRO_DESCRICAO;
            }
        });

        int i = seletorArquivo.showOpenDialog(painel);
        if (i == JFileChooser.APPROVE_OPTION) {
            return seletorArquivo.getSelectedFile();
        } else {
            return null;
        }
    }

    private String selecionarDiretorio() {
        JFileChooser seletorArquivo = new JFileChooser();
        seletorArquivo.setFileSelectionMode(JFileChooser.FILES_ONLY);
        seletorArquivo.setDialogTitle(JFILECHOOSER_DIRETORIO_TITULO);
        seletorArquivo.setFileFilter(new FileFilter() {
            @Override
            public boolean accept(File file) {
                return file.getName().toLowerCase().endsWith(EXTENSAO_EXPORTACAO) || file.isDirectory();
            }

            @Override
            public String getDescription() {
                return JFILECHOOSER_DIRETORIO_FILTRO_DESCRICAO;
            }
        });

        int i = seletorArquivo.showSaveDialog(null);
        if (i == 1) {
            return null;
        } else {
            return seletorArquivo.getSelectedFile().getAbsolutePath();
        }
    }

    private void resetar() {
        this.abilitaInterface(true);
        this.painel.getBtnConfirmar().setEnabled(false);
        this.painel.getBtnConfirmar().setText("Confirmar");
        this.painel.getTxtArquivo().setText("");
        this.painel.getTxtDiretorio().setText("");
        this.painel.getJpbProgresso().setValue(0);
        this.painel.getLblStatus().setText("...");
    }

    private void abilitaInterface(boolean cond) {
        this.painel.getBtnSelecionarArquivo().setEnabled(cond);
        this.painel.getBtnSelecionarDiretorio().setEnabled(cond);
        this.painel.getBtnConfirmar().setEnabled(cond);
        this.painel.getJspMaxParcelasAberto().setEnabled(cond);
        this.painel.getJspMaxParcelasCont().setEnabled(cond);
        this.painel.getJspMinParcelasAberto().setEnabled(cond);
        this.painel.getJspMinParcelasCont().setEnabled(cond);
        this.painel.getJspMinParcelasPagas().setEnabled(cond);
        this.painel.getTxtVlCoeficienteRed().setEnabled(cond);
        this.painel.getTxtVlCoeficienteLuc().setEnabled(cond);
        this.painel.getTxtMaxVlLiquido().setEnabled(cond);
        this.painel.getTxtMaxVlParcela().setEnabled(cond);
        this.painel.getTxtMinVlLiquido().setEnabled(cond);
        this.painel.getTxtMinVlParcela().setEnabled(cond);
    }
}
